﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;


namespace СityDelivery
{
	internal class XMLFileProcessing
	{

		private int crossroadsAmount = 0;

		private List<string> cityStreets = new List<string>();
		private List<string> streetPoints = new List<string>();
		// Для хранения вершин с координатами
		private List<Data.NodesStruct> nodesListTemp = new List<Data.NodesStruct>();

		public XMLFileProcessing() { }


		public void StartFileScanning(XmlDocument XMLFile)
		{

			if (XMLFile == null)
			{

				throw new SystemException();
			}
			else
			{

				XmlNodeList nodeList = XMLFile.SelectNodes("osm/node");
				XmlNodeList wayList = XMLFile.SelectNodes("osm/way/tag[@k='name']");

				var tempStreet = new List<string>();
				crossroadsAmount = 0;
				int nodeCount = -1;


				foreach (XmlNode nodeItem in nodeList)
				{
					double nodeID_lon;
					double nodeID_lat;
					nodeCount++;
					string nodeID = nodeItem.Attributes[0].Value;
					if (Convert.ToDouble(nodeID) <= 0)
						continue;
					if (!nodeItem.Attributes[1].Value.Equals("modify"))
					{
						nodeID_lat = double.Parse(nodeItem.Attributes[7].Value, CultureInfo.GetCultureInfo("en-US"));
						nodeID_lon = double.Parse(nodeItem.Attributes[8].Value, CultureInfo.GetCultureInfo("en-US"));
					}
					else
					{
						nodeID_lat = double.Parse(nodeItem.Attributes[8].Value, CultureInfo.GetCultureInfo("en-US"));
						nodeID_lon = double.Parse(nodeItem.Attributes[9].Value, CultureInfo.GetCultureInfo("en-US"));
					}



					foreach (XmlNode streetItem in wayList)
					{

						XmlNode wayItem = streetItem.ParentNode;
						//     if (wayItem.SelectSingleNode("tag[@k='highway']") != null) {
						//     XmlNode streetItem = null;

						string searchString = "nd[@ref=" + "'" + nodeID + "'" + "]";
						if (wayItem.SelectSingleNode(searchString) != null)
						{
							string streetName = streetItem.Attributes[1].Value;

							// Для подсчета кол-ва перекрестков	
							if (tempStreet.Contains(streetName) == false)
							{
								tempStreet.Add(streetName);
							}
							//        }
						}
					}

					string crossroad = "";

					if (tempStreet.Count() >= 2)
					{
						// Записываем все вершины перекрестков, а так же их координаты в список
						if (!Data.checkIfRepeat(Convert.ToDouble(nodeID)))
						{
							string node_streetArray = tempStreet[0];
							for (int i = 1; i < tempStreet.Count; i++)
							{
								node_streetArray += "%" + tempStreet[i];
							}
							nodesListTemp.Add(new Data.NodesStruct(Convert.ToDouble(nodeID), nodeID_lat, nodeID_lon, node_streetArray));
						}

						crossroadsAmount++;
						foreach (string str in tempStreet)
						{

							if (cityStreets.Contains(str) == false)
							{

								cityStreets.Add(str);
								streetPoints.Add("[" + nodeID + "]");
							}
							else
							{
								streetPoints[cityStreets.IndexOf(str)] += "[" + nodeID + "]";
							}
							crossroad = crossroad + " /// " + str;
						}

					}
					tempStreet.Clear();
					Data.nodesList = nodesListTemp;

				}

				foreach (string str in cityStreets)
				{
					string hhh = str + " /// " + streetPoints[cityStreets.IndexOf(str)];

				}

			}


		}

		public int GetVerticesAmount()
		{
			return crossroadsAmount;
		}

		/// <summary>
		/// Создание матрицы расстояний между перекрестками одной улицы
		/// </summary>
		public float[,] CreateMatrix()
		{
			int size = nodesListTemp.Count();
			float[,] roadMatrix = new float[size, size];

			for (int i = 0; i < nodesListTemp.Count; i++)
				for (int j = 0; j < nodesListTemp.Count; j++)
				{
					if (i != j && findMatchingStreets(nodesListTemp[i], nodesListTemp[j]))
						roadMatrix[i, j] = Data.CalculateWeights(nodesListTemp[i].NodeLat, nodesListTemp[i].NodeLon,
																 nodesListTemp[j].NodeLat, nodesListTemp[j].NodeLon);
					else if (i == j)
						roadMatrix[i, j] = -1;
				}

			return roadMatrix;
		}

		public bool findMatchingStreets(Data.NodesStruct nodesListTemp1, Data.NodesStruct nodesListTemp2)
		{
			foreach (string street1 in nodesListTemp1.StreetArray)
			{
				foreach (string street2 in nodesListTemp2.StreetArray)
				{
					if (street1.Equals(street2))
						return true;
				}
			}
			return false;
		}

		public void getInfoFromFile(XmlDocument XMLFile)
		{

			if (XMLFile == null)
			{

				throw new SystemException();
			}
			else
			{
				XmlNodeList usageList = XMLFile.SelectNodes("osm/node/tag[@k='usage']");
				List<int> Shops = new List<int>();

				foreach (XmlNode nodeItem in usageList)
				{
					XmlNode usageNode = nodeItem.ParentNode;


					string usage = nodeItem.Attributes[1].Value;

					if (usage.Equals("main"))
					{
						for (int index = 0; index < nodesListTemp.Count; index++)
						{
							Data.NodesStruct item = nodesListTemp[index];
							if (Convert.ToDouble(usageNode.Attributes[0].Value) == item.NodeId)
							{
								Data.warehouse = index;
							}
						}

					}

					if (usage.Equals("branch"))
					{
						for (int index = 0; index < nodesListTemp.Count; index++)
						{
							Data.NodesStruct item = nodesListTemp[index];
							if (Convert.ToDouble(usageNode.Attributes[0].Value) == item.NodeId)
							{
								Shops.Add(index);
							}
						}
					}

				}
				Data.Shops = Shops;
			}
		}
	}
}